package club.kynb.mall.application.statemachine.order.action;


import club.kynb.mall.application.context.OrderContext;
import club.kynb.mall.application.model.model.command.RefundOrderCancelCommand;
import club.kynb.mall.application.model.model.event.OrderApplyRefundCancelEvent;
import club.kynb.mall.order.api.IOrderRefundService;
import club.kynb.mall.order.api.IOrderService;
import club.kynb.mall.order.constant.OrderEventEnum;
import club.kynb.mall.order.constant.OrderRefundStatusEnum;
import club.kynb.mall.order.constant.OrderStatusEnum;
import club.kynb.mall.order.model.dto.OrderRefundDTO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.pizza.common.web.exception.Errors;
import org.pizza.event.publish.EventBus;
import org.pizza.statemachine.Action;
import org.pizza.util.Checker;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.Optional;

/**
 * @author kynb_club@163.com
 * @since 2021/7/9 11:18 上午
 */
@Slf4j
@Component
@AllArgsConstructor
public class OrderRefundCancelAction implements Action<OrderStatusEnum, OrderEventEnum, OrderContext> {
    private final IOrderService iOrderService;
    private final IOrderRefundService iOrderRefundService;
    private final TransactionTemplate transactionTemplate;
    private final EventBus eventBus;

    @Override
    public void execute(OrderStatusEnum from, OrderStatusEnum to, OrderEventEnum on, OrderContext orderContext) {
        final RefundOrderCancelCommand command = (RefundOrderCancelCommand) orderContext.getCommand();
        //检查退款申请状态
        final Optional<OrderRefundDTO> orderRefundOptional = iOrderRefundService.getRefundOrderBy(command.getRefundNo());
        final OrderRefundDTO orderRefundDTO = orderRefundOptional.orElseThrow(() -> Errors.BIZ.exception("传入退款申请编号有误，申请不存在"));
        Checker.ifNotThrow(OrderRefundStatusEnum.PROCESSING.getStatus().equals(orderRefundDTO.getStatus()),()->Errors.BIZ.exception("退款申请状态变更，请刷新后重试"));

        transactionTemplate.executeWithoutResult(transactionStatus -> {
            //退款申请取消
            iOrderRefundService.applyCancel(command.getRefundNo());
            //订单退款申请取消回滚状态
            iOrderService.applyRefundCancel(orderRefundDTO.getInnerOrderNo(),orderRefundDTO.getFromOrderStatus());
        });
        eventBus.publishEvent(OrderApplyRefundCancelEvent.builder().innerOrderNo(orderRefundDTO.getInnerOrderNo()).build());
    }

}
